package io.renren.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.additional.query.impl.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.additional.update.impl.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.renren.common.exception.RRException;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.RedisUtils;
import io.renren.common.validator.Assert;
import io.renren.config.RabbitConfig;
import io.renren.dao.*;
import io.renren.entity.*;
import io.renren.form.LoginForm;
import io.renren.service.ScheduleRebaseJobService;
import io.renren.service.SysMerchantService;
import io.renren.service.TokenService;
import io.renren.utils.IdWorker;
import io.renren.utils.Query;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.constraints.NotBlank;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;


@Service("sysMerchantService")
public class SysMerchantServiceImpl extends ServiceImpl<SysMerchantDao, SysMerchantEntity> implements SysMerchantService {

    @Autowired
    private TokenService tokenService;

    @Autowired
    private SysProductDao sysProductDao;

    @Autowired
    private SysReturnGoodsDao sysReturnGoodsDao;

    @Autowired
    private SysProductSkuDao sysProductSkuDao;

    @Autowired
    private MerchantCourierDao merchantCourierDao;

    @Autowired
    private SysMerchantWithdrawDao sysMerchantWithdrawDao;
    @Autowired
    private MemberDao memberDao;

    @Autowired
    private SysMerchantDao sysMerchantDao;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private MessagePostProcessor messagePostProcessor;

    @Autowired
    private ScheduleRebaseJobService scheduleRebaseJobService;

    @Autowired
    private ScheduleRebaseJobDao scheduleRebaseJobDao;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<SysMerchantEntity> page = this.page(
                new Query<SysMerchantEntity>().getPage(params),
                new QueryWrapper<SysMerchantEntity>()
        );
        return new PageUtils(page);
    }


    @Override
    public SysMerchantEntity queryByMobile(String mobile) {
        return baseMapper.selectOne(new QueryWrapper<SysMerchantEntity>().eq("mobile", mobile));
    }

    @Override
    public Map<String, Object> login(LoginForm form) {
        SysMerchantEntity user = queryByMobile(form.getMobile());
        Assert.isNull(user, "手机号或密码错误");

        //密码错误

//        System.out.println(DigestUtils.md5Hex(form.getPassword()));
        if (!user.getPassword().equals(DigestUtils.md5Hex(form.getPassword()))) {
            throw new RRException("手机号或密码错误");
        }

        //获取登录token
        TokenEntity tokenEntity = tokenService.createToken(user.getId());

        Map<String, Object> map = new HashMap<>(2);
        map.put("token", tokenEntity.getToken());
        map.put("expire", tokenEntity.getExpireTime().getTime() - System.currentTimeMillis());
        map.put("userId", tokenEntity.getUserId());
        return map;
    }

    @Override
    public PageUtils queryProducts(Integer merchantId, Map<String, Object> params) {
        String productName = (String) params.get("productName");
        IPage<SysProductSkuEntity> page = sysProductSkuDao.queryProducts(new Query<SysProductSkuEntity>().getPage(params),merchantId, productName);
        return new PageUtils(page);
    }

    @Override
    public void updateCourierFee(Integer merchantId, BigDecimal money) {
        int i = merchantCourierDao.updateCourierFee(merchantId, money);
        if (i <= 0) {
            throw new RRException("设置快递费用失败", 502);
        }
    }

    @Override
    public void reduceInventories(Integer id, Integer inventories) {
        SysProductSkuEntity sysProductSkuEntity = sysProductSkuDao.selectById(id);
        Integer i = sysProductSkuEntity.getStock() - inventories;
        if (i < 0) {
            throw new RRException("库存不足");
        }
        boolean update = new LambdaUpdateChainWrapper<>(sysProductSkuDao)
                .eq(SysProductSkuEntity::getId, id)
                .set(SysProductSkuEntity::getStock, i)
                .update();
        if (!update) {
            throw new RRException("库存更新失败");
        }
    }

    @Override
    public void memberConfirmReceipt(Map<String, Object> map) {

        String id = new IdWorker().nextId() + "";
        String s = redisUtils.get(id);
//        System.out.println(id + " " + s);
        Integer i = 1;
        if (StringUtils.isBlank(s)) {
            redisUtils.set(id, i, 30);
        }
//        System.out.println("redis: " + redisUtils.get(id));
        CorrelationData correlationData = new CorrelationData();
        correlationData.setId(id);
        rabbitTemplate.convertAndSend(RabbitConfig.EXCHANGE_DIRECT_REBASE, RabbitConfig.ROUTINGKEY_REBASE, map,messagePostProcessor, correlationData);
    }

    @Override
    public void merchantConfirmReceipt(Map<String, Object> map) {
        if (!map.containsKey("id") || !map.containsKey("inventories") || !map.containsKey("orderId")) {
            throw new RRException("传参有误");
        }
        Integer id = (Integer) map.get("id");
        Integer inventories = (Integer) map.get("inventories");
        // 商户商品库存增
        boolean update = new LambdaUpdateChainWrapper<>(sysProductSkuDao)
                .eq(SysProductSkuEntity::getId, id)
                .setSql("stock = stock + " + inventories)
                .update();
        if (!update) {
            throw new RRException("更新商户商品库存失败");
        }

        // 订单状态改
        Integer orderId = (Integer) map.get("orderId");
        update = new LambdaUpdateChainWrapper<>(sysReturnGoodsDao)
                .eq(SysReturnGoodsEntity::getOrderId, orderId)
                .set(SysReturnGoodsEntity::getState, 7)
                .update();
        if (!update) {
            throw new RRException("更新商户商品库存失败");
        }
    }

    @Override
    @Transactional
    public void agreeRefund(Map<String, Object> map) {
        Integer initState = (Integer) map.get("initState");
        boolean update;
        if (initState == 1) {
            Integer id = (Integer) map.get("id");
            Integer inventories = (Integer) map.get("inventories");
            // 商户商品库存增
             update = new LambdaUpdateChainWrapper<>(sysProductSkuDao)
                    .eq(SysProductSkuEntity::getId, id)
                    .setSql("stock = stock + " + inventories)
                    .update();
            if (!update) {
                throw new RRException("更新商户商品库存失败");
            }

        }
        // 资金 买家增 商户减
        BigDecimal merchantMoney = (BigDecimal) map.get("merchantMoney");
        BigDecimal money = (BigDecimal) map.get("money");
        if (merchantMoney.subtract(money).compareTo(new BigDecimal(0)) < 0) {
            throw new RRException("商户余额不足");
        }
        Integer userId = (Integer) map.get("userId");
        Integer merchantId = (Integer) map.get("merchantId");
        update = new LambdaUpdateChainWrapper<>(memberDao)
                .eq(MemberEntity::getUserId, userId)
                .setSql("balance = balance + " + money)
                .update();
        if (!update) {
            throw new RRException("更新用户余额失败");
        }
        update = new LambdaUpdateChainWrapper<>(sysMerchantDao)
                .eq(SysMerchantEntity::getId, merchantId)
                .setSql("money = money - " + money)
                .update();
        if (!update) {
            throw new RRException("更新商户余额失败");
        }
        // 判断买家是否确认收货
        if (initState == 3) {
            // 已收货 取消冻结返利
            Integer orderId = (Integer) map.get("orderId");
            String params = "{\"orderId\":" + orderId + "}";
            ScheduleRebaseJobEntity jobEntity = scheduleRebaseJobDao.selectOne(
                    new LambdaQueryChainWrapper<>(scheduleRebaseJobDao)
                            .eq(ScheduleRebaseJobEntity::getParams, params)
                            .select(ScheduleRebaseJobEntity::getJobId)
            );
            boolean b = scheduleRebaseJobService.removeById(jobEntity.getJobId());
            if (!b) {
                throw new RRException("取消返利定时任务失败");
            }

        }

    }

    @Override
    public void updateStock(SysProductSkuEntity skuEntity) {
        SysProductSkuEntity skuEntity1 = sysProductSkuDao.selectById(skuEntity.getId());
        skuEntity1.setStock(skuEntity.getStock());
        if (sysProductSkuDao.updateById(skuEntity1)!=1) throw new RRException("更新失败",500);
    }

    @Override
    public void updatePassword(Map<String, String> params) {
        String password = params.get("password");
        String id = params.get("id");
        String newpass = params.get("newpass");
        String oldPassword ="";
        if (StringUtils.isNotBlank(password)) {
            oldPassword=DigestUtils.md5Hex(password);
        }else throw new RRException("密码不能为空",500);
        String newPassword ="";
        if (StringUtils.isNotBlank(newpass)) {
            newPassword=DigestUtils.md5Hex(newpass);
        }else throw new RRException("密码不能为空",500);
        SysMerchantEntity sysMerchantEntity = sysMerchantDao.selectById(id);
        if (null!=sysMerchantEntity){
            if (2==sysMerchantEntity.getState())throw new RRException("商户已禁用",500);
            String old = sysMerchantEntity.getPassword();
            if (oldPassword.equals(old)){
                sysMerchantEntity.setPassword(newPassword);
                if (sysMerchantDao.updateById(sysMerchantEntity)!=1)throw new RRException("更新失败",500);
            } else {
                throw new RRException("密码不正确",500);}
        }else {
            throw new RRException("该商户不存在",500);}

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cashOut(Integer id, BigDecimal cash) {
        SysMerchantEntity sysMerchantEntity = sysMerchantDao.selectById(id);
        if (null!=sysMerchantEntity){
            BigDecimal money = sysMerchantEntity.getMoney();
            if (money.compareTo(cash)!=1)throw new RRException("请保证余额充足",500);
            BigDecimal subtract = money.subtract(cash);
            boolean update = new LambdaUpdateChainWrapper<>(sysMerchantDao).eq(SysMerchantEntity::getId, id).set(SysMerchantEntity::getMoney, subtract).update();
            if (!update){throw new RRException("更新失败");}
            SysMerchantWithdrawEntity sysMerchantWithdrawEntity = new SysMerchantWithdrawEntity();
            sysMerchantWithdrawEntity.setBank(sysMerchantEntity.getBank());
            sysMerchantWithdrawEntity.setCard(sysMerchantEntity.getCard());
            sysMerchantWithdrawEntity.setMoney(cash);
            sysMerchantWithdrawEntity.setUserName(sysMerchantEntity.getUserName());
            sysMerchantWithdrawEntity.setCreationTime(new Date());
            sysMerchantWithdrawEntity.setMobile(sysMerchantEntity.getMobile());
            sysMerchantWithdrawEntity.setMerchantName(sysMerchantEntity.getName());
            sysMerchantWithdrawEntity.setState(1);//申请中
            if (sysMerchantWithdrawDao.insert(sysMerchantWithdrawEntity)!=1){
               throw new RRException("插入失败",500);
            }

        }


    }

}
